Variable: VAR_GENERIC CONSTANT
Generic Constant Variable
Overview
The VAR_GENERIC extension provides support for generic constants at compile time in function blocks. This allows for the creation of flexible and reusable function blocks which can be adapted to different configurations (for example, buffer sizes or fixed ranges) without relying on dynamic memory allocation.
This feature is especially useful for function blocks which manage arrays or other memory structures. In addition, it allows for performance-optimized designs which are type-safe and fully resolved at compile time.
A generic constant is a variable in the VAR_GENERIC CONSTANT scope of a function block. The variable is defined only when the function block instance is declared.
Generic constants are allowed to be used in methods. This can be particularly helpful in the VAR_IN_OUT or VAR_IN_OUT CONSTANT scope.
Syntax
Declaration
Generic variables are declared between the keywords VAR_GENERIC CONSTANT and END_VAR in the declaration part of function blocks. All variables must be an integer data type (for example, INT, UINT, or DINT).
FUNCTION_BLOCK <function block name>
VAR_GENERIC CONSTANT
<generic constant name> : <integer data type> := <initial value> ; //Initial value will be overwritten
END_VAR
| Name of the function block |
| Scope for generic constants You can declare any number of generic constants in the |
| Variable name of the generic constants |
| Construct which types the generic constant. An integer data type or the subrange of an integer data type is permitted. Example:
|
| Optional Initialization ImportantThe initial value is needed only for compile checks. At runtime, the value is overwritten. |
Example:
FUNCTION BLOCK FB
VAR_GENERIC CONSTANT
size : INT;
END_VAR
VAR
buffer : ARRAY[0..size] OF BYTE;
END_VARInstantiation
A function block with generic constants can be instantiated via a parameter passing either explicitly as an expression or implicitly using a literal.
The following applies:
The part of the parameter passing which affects the
VAR_GENERIC CONSTANTscope is enclosed in angle brackets.Generic function blocks must be instantiated with parameters for all generic variables. The parameter passing must be complete. A partial specification is not permitted and will result in an error.
Either all parameters are specified explicitly, or all are specified implicitly. A mixture of explicit and implicit specifications is not permitted.
Implicit
When parameters are passed for multiple generic variables, the desired values must be strung together as a literal and comma-separated in the order which they have been declared in the
VAR_GENERIC CONSTANTscope.<5,10>
Explicit with name
When parameters are passed for multiple generic variables, all of the desired parameters must be strung together as a bracketed expression and comma-separated in a free order. As usual, an expression is enclosed in parentheses.
The expression assigns a literal, a variable, or an expression to the named generic constant using the assignment operator
:=. It is important to enclose this explicit parameter transfer in parentheses.<(Array2Size := 10), (Array1Size := 5)>
The advantage is that the parameter transfer is easily readable, therefore traceable and easily maintainable after changes.
If more variables have been declared, then additional parameters must be passed to them. Using the assignment operator
:=, these are strung together and enclosed in parentheses.
Function block FB with generic constants
FUNCTION_BLOCK FB
VAR_GENERIC CONSTANT
Array1Size : INT := 0;
Array2Size : INT := 0;
END_VAR
VAR_INPUT
MyArray1 : ARRAY[0..Array1Size-1] OF REAL;
MyArray2 : ARRAY[0..Array2Size-1] OF REAL;
END_VAR
VAR
SomeOtherParameter : INT;
END_VARInstantiation of the function block FB with simple parameter passing.
PROGRAM PLC_PRG
VAR
MyFB1 : FB<5,10> := (SomeOtherParameter:=20);
END_VAR
VAR
liArray1Size: LINT;
END_VARliArray1Size := UPPER_BOUND(MyFB1.MyArray1,1) + 1;
Function block instance MyFB2 with explicit parameter passing
PROGRAM PLC_PRG
VAR
MyFB1 : FB<5,10> := (SomeOtherParameter:=20);
MyFB2 : FB<(Array2Size:=10), (Array1Size:=5)> := (SomeOtherParameter := 10);
END_VAR
VAR
Array1Size, Array2Size : LINT;
END_VARArray1Size := UPPER_BOUND(MyFB1.MyArray1,1) + 1; Array2Size := UPPER_BOUND(MyFB1.MyArray2,1) + 1;
Inheritance with generic constants
Generic constants can also be passed to basic function blocks via inheritance.
Using constants in a function block
The constant can be used in a function block like any other constant (for example, in arrays or in string declarations). It can be used in methods, properties, or actions of the function block, but it cannot be accessed externally. This means that it behaves like a private variable.
Precompile checks
Because the final value of generic constants is not available in the function block, precompile checks are limited. It is possible to define an initialization value as follows:
FUNCTION_BLOCK FB
VAR_GENERIC CONSTANT
size : INT := 1;
END_VAR
VAR
buffer : ARRAY[0..size] OF BYTE;
END_VARThis initialization value (value 1 in the example) is used for precompile checks within the function block, but it does not have any other effect.
Examples
FUNCTION_BLOCK FB_Pou
VAR_GENERIC CONSTANT
lnstring : DINT := 10;
numstring : DINT := 100;
END_VAR
VAR
arraystring : ARRAY[0..numstring-1] OF STRING(lnstring);
END_VARPROGRAM PLC_PRG
VAR
fbPou : FB_Pou<100, 1000>;
END_VARA subrange type can be used as a generic parameter to specify a permitted range of values which is checked by the compiler.
FUNCTION_BLOCK FB_SrString
VAR_GENERIC CONSTANT
maxlen2 : INT(5..10) := 5; //subrange data type
END_VAR
VAR
arrTest : ARRAY[0..maxlen-1] OF BYTE;
END_VAR
;PROGRAM SrMain
VAR CONSTANT
cconst: INT(5..10) := 5;
END_VAR
VAR
fbMyString1 : FB_SrString<5>;
fbMyString2 : FB_SrString<(2 * cconst)>;
fbMyString3 : FB_SrcString<123>;
// ERROR: An error is reported here because 123 is not within the value range 5..10.
arrMyString : ARRAY [0..5] OF FB_SrString<6>;
END_VARThe following code demonstrates how to define a function block which can process arrays of arbitrary length. The function block has an array with a generic but constant length. "Constant" means that, although each function block instance varies in its array length, it is constant during the lifetime of the object.
This kind of construct is beneficial, for example, to a library programmer who wants to implement a generic library POU.
FUNCTION_BLOCK FB_MyString
VAR_GENERIC CONSTANT
maxlen : UDINT := 1;
END_VAR
VAR
test : ARRAY[0..maxlen-1] OF BYTE;
END_VARPROGRAM PLC_PRG
VAR CONSTANT
cconst: DINT := 1000;
END_VAR
VAR
fbMyString1 : FB_MyString<100>;
fbMyString2 : FB_MyString<(2 * cconst)>;
arrMyString : ARRAY[0..5] OF FB_MyString<6>;
END_VARInheritance
A function block can inherit from a base function block with a generic constant (EXTENDS). The inheriting function block requires its own generic constant. A specific value can then be transferred externally.
Syntax:
FUNCTION_BLOCK <function block name>
VAR_GENERIC CONSTANT
<generic constant name> : <integer data type> ;
END_VAR
EXTENDS <function block base> < <generic constant name> >
A function block with a generic constant can implement an interface (IMPLEMENTS). The interface declares a property (PROPERTY) with which the specified value can be accessed externally. The interface itself must not declare any generic constants or local variables. Interfaces have no implementation.
Syntax:
FUNCTION_BLOCK <function block name>
VAR_GENERIC CONSTANT
<generic constant name> : <integer data type> ;
END_VAR
IMPLEMENTS <interface name>
Important
When coding, make sure that the declaration of the generic constants is inserted first, followed by EXTENDS and IMPLEMENTS. This takes some getting used to, but the reason is that generic constants can also be used with base classes.
Definition of the IString interface for a generic function block.
It is strongly recommended to define an interface for generic function blocks. The interface should allow the generic function block instance to be used without knowledge of the generic constants.
The Length property enables access to the generic constant.
INTERFACE IString
METHOD Append : BOOL
VAR_INPUT
strAppend : IString;
END_VAR
METHOD Assign : BOOL
VAR_INPUT
stringIn : STRING;
END_VAR
METHOD ToString : STRING
VAR_INPUT
END_VAR
PROPERTY Length : DINTDeclaration of the function block FB_MyString with the generic constant maxlen
FUNCTION_BLOCK FB_MyString
VAR_GENERIC CONSTANT
maxlen : UDINT;
END_VAR
IMPLEMENTS IString
The function block FB_LongString is an extension of the specified function block FB_MyString.
FUNCTION_BLOCK FB_LongString EXTENDS FB_MyString<1000>
Declaration of the function block FB_MySpecialString with the generic constant maxlen2 as an extension of the specified function block FB_MyString. The function block is extended by the method METH_ToLatin.
FUNCTION_BLOCK FB_MySpecialString
VAR_GENERIC CONSTANT
maxlen2 : UDINT:= 1;
END_VAR
EXTENDS FB_MyString<maxlen2>
METHOD METH_ToLatin : STRING VAR_INPUT END_VAR
Instantiation of the function blocks with specific constants
PROGRAM PLC_PRG
VAR CONSTANT
cconst: DINT := 1000;
END_VAR
VAR
string1 : FB_MyString<100>;
string2 : FB_MyString<(2 * cconst)>;
derived1 : FB_LongString;
derived2 : FB_MySpecialString<100>;
END_VAR
Calls
string1.METH_Assign ('Welt');
string2.METH_Assign ('Hallo ');
string2.METH_Append(string1);
derived2.METH_ToLatin('Hello World');